package net.keebook.webapp.ws;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import net.keebook.webapp.dao.KeeBookDao;
import net.keebook.webapp.dao.PasswordDao;
import net.keebook.webapp.entity.KeeBook;
import net.keebook.webapp.entity.PasswordItem;
import net.keebook.webapp.entity.User;
import net.keebook.webapp.model.SessionModel;
import net.keebook.webapp.util.DateUtil;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;


@Path("/{username}/getitem")
@Stateless
public class GetItemService extends WebService {
	@Inject
	private PasswordDao passwordDao;
	@Inject
	private KeeBookDao keeBookDao;
	
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public String saveSettings(
			@Context HttpServletRequest request,
			@PathParam("username") String username,
			@DefaultValue("password") @QueryParam("auth") String auth,
			@DefaultValue("") @QueryParam("password") String password,
			@DefaultValue("") @QueryParam("keeBook") String keeBookId,
			@DefaultValue("") @QueryParam("keeBookChecksum") String keeBookChecksum,
			@DefaultValue("65535") @QueryParam("limit") int limit,
			@DefaultValue("") @QueryParam("id") String id,
			@DefaultValue("") @QueryParam("title") String title,
			@DefaultValue("") @QueryParam("group") String groupId)
	{	
		Logger.getLogger(this.getClass()).info("Incoming request");
		JSONObject result = new JSONObject();
		try {
			HttpSession httpSession = request.getSession(true);
			SessionModel sessionModel = SessionModel.getInstance(httpSession);
			
			// Authentication
			User user = authenticate(username, password, auth, sessionModel);
			if (user == null) {
				Logger.getLogger(this.getClass()).warn("Authentication failed for user " + username);
				result.put("authSuccess", false);
				result.put("success", false);
				return getResponse(result);
			}
			username = user.getUsername();
			
			// Open Key Box
			KeeBook keeBook = getKeeBook(keeBookId, keeBookChecksum);
			if (keeBook == null || !getKeeBookDao().canAccess(user.getId(), keeBook.getId())) {
				Logger.getLogger(this.getClass()).warn("Kee Book authentication failed for user " + username + " and kee book " + keeBookId);
				result.put("authSuccess", false);
				result.put("success", false);
				return getResponse(result);
			}
			
			Logger.getLogger(this.getClass()).info("User " + username + " authenticated successfully (user id: "+user.getExposableId()+" / kee book id: "+keeBook.getExposableId()+")");
			Logger.getLogger(this.getClass()).info("Request parameters: id="+id + " / limit="+limit + " / title=" + title + " / group=" + groupId);
			
			result.put("authSuccess", true);
			List<PasswordItem> items;
			TimeZone userTimezone = TimeZone.getTimeZone(user.getTimezone());
			
			if (!"".equals(id)) {
				items = new ArrayList<PasswordItem>();
				items.add(getPasswordDao().get(id));
			} else if (!"".equals(title) && !"".equals(groupId)) {
				items = getPasswordDao().getList(user.getId(), keeBook.getId(), title, groupId, null);
			} else if (!"".equals(title)) {
				items = getPasswordDao().getList(user.getId(), keeBook.getId(), title, null, null);
			} else if (!"".equals(groupId)) {
				items = getPasswordDao().getList(user.getId(), keeBook.getId(), null, groupId, null);
			} else {
				items = getPasswordDao().getList(user.getId(), keeBook.getId());
			}
			
			result.put("success", true);
			result.put("count", items.size());
			JSONArray resultList = new JSONArray();
			int i = 1;
			for (PasswordItem item : items) {
				if (i > limit) {
					break;
				}
				
				JSONObject jsonItem = new JSONObject();
				jsonItem.put("id", item.getExposableId());
				jsonItem.put("title", item.getTitle());
				jsonItem.put("username", item.getUsername());
				jsonItem.put("password", item.getPassword());
				jsonItem.put("url", item.getUrl());
				jsonItem.put("notes", item.getNotes());
				jsonItem.put("group", item.getGroup() == null ? "" : item.getGroup().getExposableId());
				
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				jsonItem.put("creationTimeUtc", sdf.format(item.getCreationTime()));
				jsonItem.put("lastModificationUtc", sdf.format(item.getLastModification()));
				
				jsonItem.put("creationTimeLocal", DateUtil.getLocalFormattedDateFromUtcTimestamp(item.getCreationTime(), userTimezone, "yyyy-MM-dd HH:mm:ss"));
				jsonItem.put("lastModificationLocal", DateUtil.getLocalFormattedDateFromUtcTimestamp(item.getLastModification(), userTimezone, "yyyy-MM-dd HH:mm:ss"));
				
				resultList.put(jsonItem);
				
				i++;
			}
			result.put("result", resultList);
		} catch (JSONException e) {
			Logger.getLogger(this.getClass()).error("JSONException while request processing", e);
			return getResponse(ERROR_RESPONSE);
		}
		
		return getResponse(result);
	}

	public PasswordDao getPasswordDao() {
		return passwordDao;
	}

	public void setPasswordDao(PasswordDao passwordDao) {
		this.passwordDao = passwordDao;
	}

	public KeeBookDao getKeeBookDao() {
		return keeBookDao;
	}

	public void setKeeBookDao(KeeBookDao keeBookDao) {
		this.keeBookDao = keeBookDao;
	}
}
